package util;

import java.io.File;
import java.io.IOException;
import java.util.Date;

import sistemaClassificador.arquivo.Arquivo;

public class Logger {

	private static StringBuilder history;
	private static int COUNTER = 0;
	private static int fileCounter = 0;
	private static final int MAX_COUNTER = 1000;
	private static boolean debugEnabled = true;
	private static boolean infoEnabled = true;
	private static boolean warningEnabled = true;
	private static boolean errorEnabled = true;
	private static boolean dateFieldEnabled = true;
	private static boolean parentFieldNameEnabled = true;
	private static boolean outPutFieldMetodEnabled = true;
	private static boolean systemOutPrintlnEnabled = true;
	private static boolean whiteSpaceBeforeEachLine = true;

	private Class parentClass = null;

	public Logger(Object parent) {
		parentClass = parent.getClass();
	}

	private StringBuilder getHistory() {
		if (history == null) {
			history = new StringBuilder(MAX_COUNTER);
		}
		return history;
	}

	public String getHistoryData() {
		return getHistory().toString();
	}

	public void debug(String value) {
		if (debugEnabled) {
			StringBuilder line = new StringBuilder();
			if (outPutFieldMetodEnabled)
				line.append("[debug]");
			if (parentFieldNameEnabled)
				line.append("[" + parentClass.getSimpleName() + "]");
			if (dateFieldEnabled)
				line.append("[" + new Date() + "]");
			line.append(">");
			line.append(value);
			historyAppender(line.toString());
		}
	}

	public void info(String value) {
		if (infoEnabled) {
			StringBuilder line = new StringBuilder();
			if (outPutFieldMetodEnabled)
				line.append("[info]");
			if (parentFieldNameEnabled)
				line.append("[" + parentClass.getSimpleName() + "]");
			if (dateFieldEnabled)
				line.append("[" + new Date() + "]");
			line.append(">");
			line.append(value);
			historyAppender(line.toString());
		}
	}

	public void warning(String value) {
		if (warningEnabled) {
			StringBuilder line = new StringBuilder();
			if (outPutFieldMetodEnabled)
				line.append("[warning]");
			if (parentFieldNameEnabled)
				line.append("[" + parentClass.getSimpleName() + "]");
			if (dateFieldEnabled)
				line.append("[" + new Date() + "]");
			line.append(">");
			line.append(value);
			historyAppender(line.toString());
		}
	}

	public void error(String value) {
		if (errorEnabled) {
			StringBuilder line = new StringBuilder();
			if (outPutFieldMetodEnabled)
				line.append("[error]");
			if (parentFieldNameEnabled)
				line.append("[" + parentClass.getSimpleName() + "]");
			if (dateFieldEnabled)
				line.append("[" + new Date() + "]");
			line.append(">");
			line.append(value);
			historyAppender(line.toString());

		}
	}

	private void historyAppender(String value) {
		if (systemOutPrintlnEnabled)
			System.out.println(value);
		if (whiteSpaceBeforeEachLine)
			getHistory().append(" ");
		if (COUNTER++ <= MAX_COUNTER)
			getHistory().append(value + "\n");
		else {
			File log = new File("history.log");
			if (log.exists()) {

				/*for (int cnt = 1; cnt <= fileCounter; cnt++) {
					File templog = new File("history.log" + cnt);
					if (templog.exists()) {
						try {
							Arquivo.renameFile("history.log" + cnt,
									"history.log" + cnt + "~");
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
					try {
						Arquivo.renameFile(log.getName(), "history.log"
								+ fileCounter);
					} catch (IOException e) {
						System.err.println("Clear the log files directory");
						e.printStackTrace();
					}
			//	}*/
				try {
					Arquivo.renameFile("history.log", "history.log"+fileCounter++);
				} catch (IOException e) {
					e.printStackTrace();
				}
				COUNTER = 0;
			}
			try {
				Arquivo.writeOnFile(history.toString(), "history.log");
			} catch (IOException e) {
				System.err
						.println("Close other aplication reading the log file");
				e.printStackTrace();
			}
		}
	}

	/**
	 * @return the debugEnabled
	 */
	public static boolean isDebugEnabled() {
		return debugEnabled;
	}

	/**
	 * @return the infoEnabled
	 */
	public static boolean isInfoEnabled() {
		return infoEnabled;
	}

	/**
	 * @return the warningEnabled
	 */
	public static boolean isWarningEnabled() {
		return warningEnabled;
	}

	/**
	 * @return the errorEnabled
	 */
	public static boolean isErrorEnabled() {
		return errorEnabled;
	}

	/**
	 * @return the dateFieldEnabled
	 */
	public static boolean isDateFieldEnabled() {
		return dateFieldEnabled;
	}

	/**
	 * @return the classFieldNameEnabled
	 */
	public static boolean isClassFieldNameEnabled() {
		return parentFieldNameEnabled;
	}

	/**
	 * @return the outPutFieldMetodEnabled
	 */
	public static boolean isOutPutFieldMetodEnabled() {
		return outPutFieldMetodEnabled;
	}

	/**
	 * @param history
	 *            the history to set
	 */
	public static void setHistory(StringBuilder history) {
		Logger.history = history;
	}

	/**
	 * @param debugEnabled
	 *            the debugEnabled to set
	 */
	public static void setDebugEnabled(boolean debugEnabled) {
		Logger.debugEnabled = debugEnabled;
	}

	/**
	 * @param infoEnabled
	 *            the infoEnabled to set
	 */
	public static void setInfoEnabled(boolean infoEnabled) {
		Logger.infoEnabled = infoEnabled;
	}

	/**
	 * @param warningEnabled
	 *            the warningEnabled to set
	 */
	public static void setWarningEnabled(boolean warningEnabled) {
		Logger.warningEnabled = warningEnabled;
	}

	/**
	 * @param errorEnabled
	 *            the errorEnabled to set
	 */
	public static void setErrorEnabled(boolean errorEnabled) {
		Logger.errorEnabled = errorEnabled;
	}

	/**
	 * @param dateFieldEnabled
	 *            the dateFieldEnabled to set
	 */
	public static void setDateFieldEnabled(boolean dateFieldEnabled) {
		Logger.dateFieldEnabled = dateFieldEnabled;
	}

	/**
	 * @param classFieldNameEnabled
	 *            the classFieldNameEnabled to set
	 */
	public static void setClassFieldNameEnabled(boolean classFieldNameEnabled) {
		Logger.parentFieldNameEnabled = classFieldNameEnabled;
	}

	/**
	 * @param outPutFieldMetodEnabled
	 *            the outPutFieldMetodEnabled to set
	 */
	public static void setOutPutFieldMetodEnabled(
			boolean outPutFieldMetodEnabled) {
		Logger.outPutFieldMetodEnabled = outPutFieldMetodEnabled;
	}

	/**
	 * @return the systemOutPrintlnEnabled
	 */
	public static boolean isSystemOutPrintlnEnabled() {
		return systemOutPrintlnEnabled;
	}

	/**
	 * @param systemOutPrintlnEnabled
	 *            the systemOutPrintlnEnabled to set
	 */
	public static void setSystemOutPrintlnEnabled(
			boolean systemOutPrintlnEnabled) {
		Logger.systemOutPrintlnEnabled = systemOutPrintlnEnabled;
	}
}
